package com.sugon.springboot.filter;

import com.alibaba.nacos.client.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.concurrent.TimeUnit;
@Component
public class AuthFilter  implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String TOKEN_HEADER_KEY = "auth_token";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("********** 自定义全局过滤器被执行 ***********");
        //获取 token 参数，注意使用的是 getFirst 方法，getFirst 并不是获取第一个的意思
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if(!StringUtils.isEmpty(token)){
            if("123".equals(token)){//模拟 token 鉴权逻辑，实际项目应该是从 Redis 里获取
                System.out.println("鉴权成功！token="+token);
                return chain.filter(exchange);
            }
        }
        ServerHttpResponse response = exchange.getResponse();
        //响应类型
        response.getHeaders().add("Content-Type","application/json;charset=utf-8");
        //响应状态码：401，未授权
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //响应内容
        String message = HttpStatus.UNAUTHORIZED.getReasonPhrase();
        DataBuffer buffer = response.bufferFactory().wrap(message.getBytes());
        return response.writeWith(Mono.just(buffer));

    }


    @Override
    public int getOrder() {
        // 优先级 越小越优先
        return 0;
    }

    /**
     * 从redis中获取用户id
     * 在登录操作时候 登陆成功会生成一个token, redis得key为auth_token:token 值为用户id
     */
    private String getUserIdByToken(String token) {
        String redisKey = String.join(":", "auth_token", token);
        return redisTemplate.opsForValue().get(redisKey);
    }

    /**
     * 重置token过期时间
     */
    private void resetTokenExpirationTime(String token, String userId) {
        String redisKey = String.join(":", "auth_token", token);
        redisTemplate.opsForValue().set(redisKey, userId, 2, TimeUnit.HOURS);
    }


    /**
     * 获取token
     */
    private static String getToken(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        // 从请求头获取token
        String token = headers.getFirst(TOKEN_HEADER_KEY);
        if (StringUtils.isBlank(token)) {
            // 请求头无token则从url获取token
            token = request.getQueryParams().getFirst(TOKEN_HEADER_KEY);
        }
        if (StringUtils.isBlank(token)) {
            // 请求头和url都没有token则从cookies获取
            HttpCookie cookie = request.getCookies().getFirst(TOKEN_HEADER_KEY);
            if (cookie != null) {
                token = cookie.getValue();
            }
        }
        return token;
    }
}

